#pragma once

#include "Types.h"
#include "DLL.h"
#include "TransformTool.h"

#include <MyViews/ZoomBench.h>
#include <MyFC/Event.h>

namespace My {

class TransformOwner {
public:
	virtual Affine GetTransform() const = 0;
	virtual rect<double> GetBounds() const = 0;
	virtual rect<double> GetMargins() const = 0;
	virtual void SetTransform(const Affine &, const String & action = String()) = 0;
};

class DLL_API TransformEditor : 
	public CCmdTarget,
	public EventDispatcher {
public:
	class Event : public My::Event {
	public:
		TransformEditor &	m_Editor;
		Event(TransformEditor & e) : m_Editor(e) { }
	};
	class TransformChange : public Event {
	public:
		TransformChange(TransformEditor & e) : Event(e) { }
	};
	class AnchorChange : public Event {
	public:
		AnchorChange(TransformEditor & e) : Event(e) { }
	};
	class StateChange : public Event {
	public:
		StateChange(TransformEditor & e) : Event(e) { }
	};
public:
	TransformEditor(ZoomBench &);
	~TransformEditor();
public:
	ZoomBench & GetBench();
	TransformOwner * GetTransformOwner() const;
	const Affine & GetTransform() const
		{ return m_Transform; }
	bool IsOpen() const;
	TransformTool * GetTransformTool() const
		{ return &m_TransformTool; }
public:
	void Open(TransformOwner &);
	void Close();
	void PaintRect(CDC *, const CRect &);
	void SetTransform(const Affine &);
	/// Sets transform that maps p[i] to q[i]
	void CalcTransform(const point<double> p[3], const point<double> q[3]);
	void Synchronize();
	void UpdateTransform();
private:
	ZoomBench &			m_Bench;
	TransformOwner *	m_pOwner;
	Tool *				m_pTool;
	Affine				m_Transform;
	bool				m_Sync; ///< this variable is true during Syncronize() operation
	mutable TransformTool		m_TransformTool;
protected:
	DECLARE_MESSAGE_MAP()
public:
};

} // My
